package com.example.config;

import com.alibaba.fastjson.parser.ParserConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author: ChenZhiXiang
 * @description: Redis配置类
 * @date:
 */
@Configuration
public class RedisConfig {

    @Autowired
    private RedisConfigProperties redis;

    @Bean
    public RedisSerializer fastJson2JsonRedisSerializer(){
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        return new FastJson2JsonRedisSerializer<>(Object.class);
    }

    /**
     * 连接池配置信息
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        //最大连接数
        jedisPoolConfig.setMaxTotal(redis.getMaxTotal());
        //最小空闲连接数
        jedisPoolConfig.setMinIdle(redis.getMinIdle());
        // 最大空闲接连
        jedisPoolConfig.setMaxIdle(redis.getMaxIdle());
        //当池内没有可用连接时，最大等待时间
        jedisPoolConfig.setMaxWaitMillis(redis.getMaxWait());
        //其他属性可以自行添加
        return jedisPoolConfig;
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(redis.getDatabase());
        // 设置redis服务器的host或者ip地址
        redisStandaloneConfiguration.setHostName(redis.getHost());
        redisStandaloneConfiguration.setPort(redis.getPort());
        // 密码
        redisStandaloneConfiguration.setPassword(redis.getPassword());
        // 获得默认的连接池构造
        // 这里需要注意的是，edisConnectionFactoryJ对于Standalone模式的没有（RedisStandaloneConfiguration，JedisPoolConfig）的构造函数，对此
        // 我们用JedisClientConfiguration接口的builder方法实例化一个构造器，还得类型转换
        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcf = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
        // 修改我们的连接池配置
        jpcf.poolConfig(jedisPoolConfig());
        // 通过构造器来构造jedis客户端配置
        JedisClientConfiguration jedisClientConfiguration = jpcf.build();
        return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory, RedisSerializer fastJson2JsonRedisSerializer) {
        StringRedisTemplate redisTemplate = new StringRedisTemplate(factory);
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        //redis 开启事务
        redisTemplate.setEnableTransactionSupport(true);
        //hash 使用jdk 的序列化将下列换成 new JdkSerializationRedisSerializer()
        redisTemplate.setHashValueSerializer(fastJson2JsonRedisSerializer);
        //StringRedisSerializer key 序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        //keySerializer 对key的默认序列化器。默认值是StringSerializer
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // valueSerializer
        redisTemplate.setValueSerializer(fastJson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

}
